//
//  Inherit.swift
//  cnswift-demo
//
//  Created by YangWei on 2020/12/31.
//  Copyright © 2020 YangWei. All rights reserved.
//

import UIKit

/// 1 定义一个基类
/// 定义一个 Vehicle 的基类
class Vehicle {
    // 默认值是 0.0 的存储型属性（属性类型推断为 Double）
    var currentSpeed = 0.0
    
    // 一个 String 类型的只读计算型属性 description，使用 currentSpeed 属性的值创建对于车辆的描述
    var description: String {
        return "traveling at \(currentSpeed) miles per hour"
    }
    
    // 不为 Vehicle 实例做任何事，之后将会被 Vehicle 的子类定制
    func makeNoise() {
        // 什么也不做——因为车辆不一定会有噪音
    }
}

/// 2 子类生成
/// 定义一个叫 Bicycle 的子类，继承自超类 Vehicle
/// 自动继承 Vehicle 类的所有特性，比如 currentSpeed 和 description 属性，还有 makeNoise() 方法
class Bicycle: Vehicle {
    // 定义一个默认值为 false 的存储型属性 hasBasket（属性推断为 Bool）
    // 即默认情况，创建的新 Bicycle 实例不会有一个篮子（即 hasBasket 属性默认为 false）
    var hasBasket = false
}

/// 2 子类生成
/// 为 Bicycle 创建了一个名为 Tandem（双人自行车）的子类：
/// Tandem 从 Bicycle 继承了所有的属性与方法，同时继承了 Vehicle 的所有属性与方法。
class Tandem: Bicycle {
    // 增加一个新存储型属性，默认值为 0
    var currentNumberOfPassengers = 0
}

/// 3.2 重写方法
/// 定义 Vehicle 一个新的子类，叫 Train
class Train: Vehicle {
    // 重写从 Vehicle 类继承来的 makeNoise() 方法
    override func makeNoise() {
        print("Choo Choo")
    }
}

/// 3.3.1 重写属性的 Getters 和 Setters
/// 定义一个新类 Car，是 Vehicle 的子类
class Car: Vehicle {
    // 引入了一个新的存储型属性叫做 gear，默认值为整数 1
    var gear = 1
    
    // 重写了继承自 Vehicle 的 description 属性，提供包含当前档位的自定义描述
    override var description: String {
        // 首先调用 super.description 返回 Vehicle 类的 description 属性。
        // 之后，Car 类版本 description 在末尾增加一些额外的文本来提供关于当前档位的信息
        return super.description + " in gear \(gear)"
    }
}

/// 3.4 重写属性观察器
/// 定义了一个新类 AutomaticCar， Car 的子类
/// 表示自动档汽车，可以根据当前的速度自动选择合适的档位
class AutomaticCar: Car {
    override var currentSpeed: Double {
        // 设置 AutomaticCar 的 currentSpeed 属性，属性的 didSet 观察器就会自动地设置 gear 属性，为新的速度选择一个合适的档位
        didSet {
            gear = Int(currentSpeed / 10.0) + 1
        }
    }
}

class Inheritance: SWDBaseObject {
    
    class func run() {
        
        let inheritance = Inheritance()
        
        // 1
        inheritance.definingABaseClass()
        
        // 2
        inheritance.subclassing()
        
        // 3.2
        inheritance.overridingMethods()
        
        // 3.3.1
        inheritance.overridingPropertyGettersAndSetters()
        
        // 3.4
        inheritance.overridingPropertyObservers()
    }
    
    /// 1 定义一个基类
    func definingABaseClass() {
        let title = "1 定义一个基类";
        printStartLine(title)
        
        // 创建一个新的 Vehicle 实例
        let someVehicle = Vehicle()

        // 访问它的 description 属性来打印车辆的当前速度
        print("Vehicle: \(someVehicle.description)")
        // 打印“Vehicle: traveling at 0.0 miles per hour”
        
        printEndLine(title)
    }
    
    /// 2 子类生成
    func subclassing() {
        let title = "2 子类生成";
        printStartLine(title)
        
        // 创建该实例之后，你可以为 Bicycle 实例设置 hasBasket 属性为 ture
        let bicycle = Bicycle()
        bicycle.hasBasket = true

        // 修改 Bicycle 实例所继承的 currentSpeed 属性，和查询实例所继承的 description 属性
        bicycle.currentSpeed = 15.0
        print("Bicycle: \(bicycle.description)")
        // 打印“Bicycle: traveling at 15.0 miles per hour”
        
        // 创建了一个 Tandem 的实例，可以使用它所有的新属性和继承的属性，还能查询从 Vehicle 继承来的只读属性 description
        let tandem = Tandem()
        tandem.hasBasket = true
        tandem.currentNumberOfPassengers = 2
        tandem.currentSpeed = 22.0
        print("Tandem: \(tandem.description)")
        // 打印：“Tandem: traveling at 22.0 miles per hour”
        
        printEndLine(title)
    }
    
    /// 3.2 重写方法
    func overridingMethods() {
        let title = "3.2 重写方法";
        printStartLine(title)
        
        // 创建一个 Train 的新实例，并调用它的 makeNoise() 方法，发现 Train 版本的方法被调用：
        let train = Train()
        train.makeNoise()
        // 打印“Choo Choo”
        
        printEndLine(title)
    }
    
    /// 3.3.1 重写属性的 Getters 和 Setters
    func overridingPropertyGettersAndSetters() {
        let title = "3.3.1 重写属性的 Getters 和 Setters";
        printStartLine(title)
        
        //  Car 的实例并且设置了它的 gear 和 currentSpeed 属性
        let car = Car()
        car.currentSpeed = 25.0
        car.gear = 3
        // 可以看到它的 description 返回了 Car 中的自定义描述：
        print("Car: \(car.description)")
        // 打印“Car: traveling at 25.0 miles per hour in gear 3”
        
        printEndLine(title)
    }
    
    
    /// 3.4 重写属性观察器
    func overridingPropertyObservers() {
        let title = "3.4 重写属性观察器";
        printStartLine(title)
        
        // 速度为 35.0 时，档位为 4：
        let automatic = AutomaticCar()
        automatic.currentSpeed = 35.0
        print("AutomaticCar: \(automatic.description)")
        // 打印“AutomaticCar: traveling at 35.0 miles per hour in gear 4”
        
        printEndLine(title)
    }
}
